package com.yc.cloud.admin.service.impl;

import com.yc.cloud.common.orm.CommonPage;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelCreateReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelQueryReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelUpdateReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelVersionQueryReqDTO;
import com.yc.cloud.admin.vo.AlgModelVersionVo;
import com.yc.cloud.admin.vo.AlgModelVo;
import com.yc.cloud.api.enums.PublishStatusEnum;
import com.yc.cloud.entity.AlgModel;
import com.yc.cloud.mapper.AlgModelMapper;
import com.yc.cloud.admin.service.AlgModelService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;
import java.util.Objects;
import java.util.List;
import java.util.stream.Collectors;
import com.yc.cloud.admin.service.AlgModelVersionService;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * <p>
 * 算法模型表 服务实现类
 * </p>
 *
 * @author kinggu
 * @since 2025-07-11
 */
@Service
public class AlgModelServiceImpl extends ServiceImpl<AlgModelMapper, AlgModel> implements AlgModelService {

    @Autowired
    private AlgModelVersionService algModelVersionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(AlgModelCreateReqDTO createReqDTO) {
        AlgModel entity = new AlgModel();
        BeanUtils.copyProperties(createReqDTO, entity);
        return save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(AlgModelUpdateReqDTO updateReqDTO) {
        AlgModel entity = new AlgModel();
        BeanUtils.copyProperties(updateReqDTO, entity);
        return updateById(entity);
    }

    @Override
    public CommonPage<AlgModelVo> list(BasePageReqDTO pageReqDTO) {
        // 调用新的方法，保持向后兼容
        if (pageReqDTO instanceof AlgModelQueryReqDTO) {
            return list((AlgModelQueryReqDTO) pageReqDTO);
        }
        
        AlgModelQueryReqDTO queryReqDTO = new AlgModelQueryReqDTO();
        BeanUtils.copyProperties(pageReqDTO, queryReqDTO);
        return list(queryReqDTO);
    }
    
    @Override
    public CommonPage<AlgModelVo> list(AlgModelQueryReqDTO queryReqDTO) {
        QueryWrapper<AlgModel> queryWrapper = new QueryWrapper<>();
        
        // 1. 添加筛选条件
        if (queryReqDTO.getAlgorithmId() != null) {
            queryWrapper.eq("algorithm_id", queryReqDTO.getAlgorithmId());
        }
        
        // 2. 排序
        if (StrUtil.isNotEmpty(queryReqDTO.getSortBy())) {
            if (Objects.equals(BasePageReqDTO.ORDER_DESC, queryReqDTO.getOrder())) {
                queryWrapper.orderByDesc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            } else {
                queryWrapper.orderByAsc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            }
        } else {
            // 默认按创建时间倒序
            queryWrapper.orderByDesc("create_time");
        }
        
        // 3. 关键字模糊查询
        if (StrUtil.isNotEmpty(queryReqDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper.like("name", queryReqDTO.getKeyword())
                                             .or()
                                             .like("description", queryReqDTO.getKeyword()));
        }
        
        // 4. 分页查询
        CommonPage<AlgModelVo> result;
        if (Boolean.TRUE.equals(queryReqDTO.getPage())) {
            IPage<AlgModel> page = new Page<>(queryReqDTO.getPageNum(), queryReqDTO.getPageSize());
            IPage<AlgModel> dbPage = baseMapper.selectPage(page, queryWrapper);
            result = CommonPage.restPage(dbPage.convert(this::convertToVo));
        } else {
            List<AlgModel> allRecords = baseMapper.selectList(queryWrapper);
            result = new CommonPage<>();
            result.setList(convertToVoList(allRecords));
            result.setTotal((long) allRecords.size());
            result.setPageNum(1);
            result.setPageSize(allRecords.size());
            result.setTotalPage(1);
        }
        
        // 5. 为每个模型查询所有版本信息 (仅当includeVersions=true时执行)
        if (Boolean.TRUE.equals(queryReqDTO.getIncludeVersions()) && result.getList() != null && !result.getList().isEmpty()) {
            for (AlgModelVo modelVo : result.getList()) {
                // 查询该模型的所有版本信息
                AlgModelVersionQueryReqDTO versionQueryReqDTO = new AlgModelVersionQueryReqDTO();
                versionQueryReqDTO.setModelId(modelVo.getId());
                versionQueryReqDTO.setPage(false); // 不分页，获取所有版本
                CommonPage<AlgModelVersionVo> versionPage = algModelVersionService.list(versionQueryReqDTO);
                if (versionPage != null && versionPage.getList() != null) {
                    modelVo.setVersionList(versionPage.getList());
                }
            }
        }
        
        return result;
    }

    @Override
    public AlgModelVo getVOById(Long id) {
        AlgModel entity = getById(id);
        return convertToVo(entity);
    }

    @Override
    public List<AlgModelVo> convertToVoList(List<AlgModel> entityList) {
        if (entityList == null) {
            return null;
        }
        return entityList.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }

    private AlgModelVo convertToVo(AlgModel entity) {
        if (entity == null) {
            return null;
        }
        AlgModelVo vo = new AlgModelVo();
        BeanUtils.copyProperties(entity, vo);
        // 通过模型ID查询模型历史版本中已发布的版本
        AlgModelVersionVo algModelVersionVo = algModelVersionService.getPublishedVersionByModelId(entity.getId());
        if (algModelVersionVo != null) {
            vo.setPublishedVersion(algModelVersionVo.getModelVersion());
            vo.setPublishedStatus(PublishStatusEnum.PUBLISHED.getValue());
        } else {
            vo.setPublishedStatus(PublishStatusEnum.UNPUBLISHED.getValue());
        }
        return vo;
    }

    @Override
    public AlgModel get(Long id) {
        return getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        return removeById(id);
    }
}